﻿// -------------------------------------------------------------------------
//    @FileName         :    TestNFShmHashSetWithListAdvanced.h
//    @Author           :    gaoyi
//    @Date             :    2024-01-20
//    @Email			:    445267987@qq.com
//    @Module           :    TestNFShmHashSetWithListAdvanced
//
// -------------------------------------------------------------------------

#pragma once

#include "NFComm/NFShmStl/NFShmHashSetWithList.h"
#include <gtest/gtest.h>
#include <string>
#include <vector>
#include <set>
#include <algorithm>
#include <chrono>
#include <random>

/**
 * @file TestNFShmHashSetWithListAdvanced.h
 * @brief NFShmHashSetWithList 高级链表排序接口的单元测试
 * 
 * 本文件专门测试集合容器的以下高级接口：
 * 1. insert_list_sorted() - 按有序位置插入元素（唯一元素）
 * 2. emplace_list_sorted() - 原地构造并按有序位置插入
 * 3. emplace_hint_list_sorted() - 带提示的原地构造并按有序位置插入
 * 4. move_to_list_node_front() - 将节点移到链表前端
 * 5. move_to_list_node_back() - 将节点移到链表后端
 * 6. move_to_list_sorted() - 将节点移到正确的有序位置
 * 
 * 特别关注Set容器的特性：
 * - 元素唯一性
 * - 基于值的排序
 * - 高效的查找和插入
 */

// 测试用的任务信息
struct TaskInfo
{
    int priority;
    std::string name;
    std::string category;

    TaskInfo() : priority(0)
    {
    }

    TaskInfo(int p, const std::string& n, const std::string& c) : priority(p), name(n), category(c)
    {
    }

    bool operator==(const TaskInfo& other) const
    {
        return priority == other.priority && name == other.name && category == other.category;
    }

    bool operator<(const TaskInfo& other) const
    {
        if (priority != other.priority)
            return priority < other.priority;
        if (category != other.category)
            return category < other.category;
        return name < other.name;
    }
};

// TaskInfo的哈希函数
namespace std
{
    template <>
    struct hash<TaskInfo>
    {
        size_t operator()(const TaskInfo& t) const
        {
            return std::hash<int>{}(t.priority) ^ (std::hash<std::string>{}(t.name) << 1) ^ (std::hash<std::string>{}(t.category) << 2);
        }
    };
}

/**
 * @brief 测试Set的insert_list_sorted接口
 */
TEST(NFShmHashSetWithListAdvancedTest, InsertListSorted)
{
    printf("========== Set InsertListSorted Test ==========\n");

    NFShmHashSetWithList<int, 100> numberSet;
    numberSet.CreateInit();

    // 测试1：使用默认比较器插入数字
    printf("Test 1: Insert numbers with default comparator\n");

    auto result1 = numberSet.insert_list_sorted(85);
    EXPECT_TRUE(result1.second); // 新插入成功
    EXPECT_EQ(*result1.first, 85);

    auto result2 = numberSet.insert_list_sorted(92);
    EXPECT_TRUE(result2.second); // 新插入成功
    EXPECT_EQ(*result2.first, 92);

    auto result3 = numberSet.insert_list_sorted(78);
    EXPECT_TRUE(result3.second); // 新插入成功
    EXPECT_EQ(*result3.first, 78);

    auto result4 = numberSet.insert_list_sorted(89);
    EXPECT_TRUE(result4.second); // 新插入成功
    EXPECT_EQ(*result4.first, 89);

    // 尝试插入重复元素
    auto result5 = numberSet.insert_list_sorted(85);
    EXPECT_FALSE(result5.second); // 重复元素，插入失败
    EXPECT_EQ(*result5.first, 85); // 但返回已存在的元素

    printf("After insert_list_sorted (should be sorted):\n");
    std::vector<int> values;
    for (auto it = numberSet.list_begin(); it != numberSet.list_end(); ++it)
    {
        printf("  %d\n", *it);
        values.push_back(*it);
    }

    // 验证按value升序排列
    EXPECT_TRUE(std::is_sorted(values.begin(), values.end()));
    std::vector<int> expected_values = {78, 85, 89, 92};
    EXPECT_EQ(values, expected_values);
    EXPECT_EQ(numberSet.size(), 4);

    numberSet.clear();

    // 测试2：使用自定义比较器（降序）
    printf("\nTest 2: Custom comparator (descending)\n");

    auto comp = [](const int& a, const int& b) { return a > b; };

    numberSet.insert_list_sorted(85, comp);
    numberSet.insert_list_sorted(92, comp);
    numberSet.insert_list_sorted(78, comp);
    numberSet.insert_list_sorted(89, comp);

    printf("After insert_list_sorted with descending comparator:\n");
    std::vector<int> desc_values;
    for (auto it = numberSet.list_begin(); it != numberSet.list_end(); ++it)
    {
        printf("  %d\n", *it);
        desc_values.push_back(*it);
    }

    // 验证按value降序排列
    EXPECT_TRUE(std::is_sorted(desc_values.begin(), desc_values.end(), std::greater<int>()));
    std::vector<int> expected_desc_values = {92, 89, 85, 78};
    EXPECT_EQ(desc_values, expected_desc_values);

    printf("Set InsertListSorted test passed\n");
}

/**
 * @brief 测试Set的emplace_list_sorted接口
 */
TEST(NFShmHashSetWithListAdvancedTest, EmplaceListSorted)
{
    printf("========== Set EmplaceListSorted Test ==========\n");

    NFShmHashSetWithList<TaskInfo, 100> taskSet;
    taskSet.CreateInit();

    // 测试1：使用默认比较器原地构造任务
    printf("Test 1: Emplace tasks with default comparator\n");

    auto result1 = taskSet.emplace_list_sorted(3, "Review Code", "Development");
    EXPECT_TRUE(result1.second);
    EXPECT_EQ(result1.first->priority, 3);

    auto result2 = taskSet.emplace_list_sorted(1, "Fix Bug", "Development");
    EXPECT_TRUE(result2.second);
    EXPECT_EQ(result2.first->priority, 1);

    auto result3 = taskSet.emplace_list_sorted(5, "Meeting", "Management");
    EXPECT_TRUE(result3.second);
    EXPECT_EQ(result3.first->priority, 5);

    auto result4 = taskSet.emplace_list_sorted(2, "Test Feature", "QA");
    EXPECT_TRUE(result4.second);
    EXPECT_EQ(result4.first->priority, 2);

    // 尝试插入重复任务
    auto result5 = taskSet.emplace_list_sorted(1, "Fix Bug", "Development");
    EXPECT_FALSE(result5.second); // 重复任务，插入失败

    printf("After emplace_list_sorted (should be sorted by priority):\n");
    std::vector<int> priorities;
    for (auto it = taskSet.list_begin(); it != taskSet.list_end(); ++it)
    {
        printf("  Priority:%d '%s' (%s)\n", it->priority, it->name.c_str(), it->category.c_str());
        priorities.push_back(it->priority);
    }

    // 验证按priority升序排列
    EXPECT_TRUE(std::is_sorted(priorities.begin(), priorities.end()));
    EXPECT_EQ(taskSet.size(), 4);

    taskSet.clear();

    // 测试2：使用自定义比较器（按category升序，category相同按priority降序）
    printf("\nTest 2: Custom comparator (by category asc, then priority desc)\n");

    auto comp = [](const TaskInfo& a, const TaskInfo& b)
    {
        if (a.category != b.category)
            return a.category < b.category;
        return a.priority > b.priority;
    };

    taskSet.emplace_list_sorted_comp(comp, 3, "Review Code", "Development");
    taskSet.emplace_list_sorted_comp(comp, 1, "Fix Bug", "Development");
    taskSet.emplace_list_sorted_comp(comp, 5, "Meeting", "Management");
    taskSet.emplace_list_sorted_comp(comp, 2, "Test Feature", "QA");
    taskSet.emplace_list_sorted_comp(comp, 4, "Write Doc", "Development");

    printf("After emplace_list_sorted with custom comparator:\n");
    for (auto it = taskSet.list_begin(); it != taskSet.list_end(); ++it)
    {
        printf("  Priority:%d '%s' (%s)\n", it->priority, it->name.c_str(), it->category.c_str());
    }

    // 验证排序正确性
    std::vector<std::pair<std::string, int>> category_priority_pairs;
    for (auto it = taskSet.list_begin(); it != taskSet.list_end(); ++it)
    {
        category_priority_pairs.emplace_back(it->category, it->priority);
    }

    for (size_t i = 1; i < category_priority_pairs.size(); ++i)
    {
        auto& prev = category_priority_pairs[i - 1];
        auto& curr = category_priority_pairs[i];

        bool valid_order = (curr.first > prev.first) || (curr.first == prev.first && curr.second <= prev.second);
        EXPECT_TRUE(valid_order);
    }

    printf("Set EmplaceListSorted test passed\n");
}

/**
 * @brief 测试Set的emplace_hint_list_sorted接口
 */
TEST(NFShmHashSetWithListAdvancedTest, EmplaceHintListSorted)
{
    printf("========== Set EmplaceHintListSorted Test ==========\n");

    NFShmHashSetWithList<std::string, 100> wordSet;
    wordSet.CreateInit();

    // 测试：emplace_hint_list_sorted应该忽略hint参数，正确排序
    printf("Test: emplace_hint_list_sorted should maintain sorted order\n");

    auto it1 = wordSet.emplace_hint_list_sorted("zebra");
    EXPECT_EQ(*it1, "zebra");

    auto it2 = wordSet.emplace_hint_list_sorted("apple");
    EXPECT_EQ(*it2, "apple");

    auto it3 = wordSet.emplace_hint_list_sorted("banana");
    EXPECT_EQ(*it3, "banana");

    auto it4 = wordSet.emplace_hint_list_sorted("cherry");
    EXPECT_EQ(*it4, "cherry");

    printf("After emplace_hint_list_sorted:\n");
    std::vector<std::string> words;
    for (auto it = wordSet.list_begin(); it != wordSet.list_end(); ++it)
    {
        printf("  %s\n", it->c_str());
        words.push_back(*it);
    }

    // 验证按字母升序排列
    EXPECT_TRUE(std::is_sorted(words.begin(), words.end()));
    std::vector<std::string> expected_words = {"apple", "banana", "cherry", "zebra"};
    EXPECT_EQ(words, expected_words);

    // 测试带自定义比较器的版本
    wordSet.clear();

    auto comp = [](const std::string& a, const std::string& b) { return a > b; };

    wordSet.emplace_hint_list_sorted_comp(comp, "zebra");
    wordSet.emplace_hint_list_sorted_comp(comp, "apple");
    wordSet.emplace_hint_list_sorted_comp(comp, "banana");
    wordSet.emplace_hint_list_sorted_comp(comp, "cherry");

    printf("\nAfter emplace_hint_list_sorted with descending comparator:\n");
    std::vector<std::string> desc_words;
    for (auto it = wordSet.list_begin(); it != wordSet.list_end(); ++it)
    {
        printf("  %s\n", it->c_str());
        desc_words.push_back(*it);
    }

    // 验证按字母降序排列
    EXPECT_TRUE(std::is_sorted(desc_words.begin(), desc_words.end(), std::greater<std::string>()));
    std::vector<std::string> expected_desc_words = {"zebra", "cherry", "banana", "apple"};
    EXPECT_EQ(desc_words, expected_desc_words);

    printf("Set EmplaceHintListSorted test passed\n");
}

/**
 * @brief 测试Set的move_to_list_node_front接口
 */
TEST(NFShmHashSetWithListAdvancedTest, MoveToListNodeFront)
{
    printf("========== Set MoveToListNodeFront Test ==========\n");

    NFShmHashSetWithList<int, 100> numberSet;
    numberSet.CreateInit();

    // 插入数据并排序
    numberSet.insert(85);
    numberSet.insert(92);
    numberSet.insert(78);
    numberSet.insert(89);
    numberSet.sort_list(); // 按value升序排序

    printf("Original sorted order:\n");
    for (auto it = numberSet.list_begin(); it != numberSet.list_end(); ++it)
    {
        printf("  %d\n", *it);
    }

    // 测试1：使用默认比较器将元素移到前端合适位置
    printf("\nTest 1: Move element to correct front position with default comparator\n");

    auto target_it = numberSet.find(89);
    EXPECT_NE(target_it, numberSet.end());

    numberSet.move_to_list_node_front(target_it);

    printf("After moving 89 to front (should maintain sorted order):\n");
    std::vector<int> values_after_move;
    for (auto it = numberSet.list_begin(); it != numberSet.list_end(); ++it)
    {
        printf("  %d\n", *it);
        values_after_move.push_back(*it);
    }

    // 验证仍然保持sorted order
    EXPECT_TRUE(std::is_sorted(values_after_move.begin(), values_after_move.end()));

    // 测试2：使用自定义比较器
    printf("\nTest 2: Move element with custom comparator (descending)\n");

    auto comp = [](const int& a, const int& b) { return a > b; };
    auto element_it = numberSet.find(78);
    EXPECT_NE(element_it, numberSet.end());

    numberSet.move_to_list_node_front(element_it, comp);

    printf("After moving 78 to front with descending comparator:\n");
    for (auto it = numberSet.list_begin(); it != numberSet.list_end(); ++it)
    {
        printf("  %d\n", *it);
    }

    // 测试3：使用链表迭代器
    printf("\nTest 3: Move using list_iterator\n");

    auto list_it = numberSet.list_begin();
    ++list_it; // 指向第二个元素

    numberSet.move_to_list_node_front(list_it);

    printf("After moving second element to front:\n");
    for (auto it = numberSet.list_begin(); it != numberSet.list_end(); ++it)
    {
        printf("  %d\n", *it);
    }

    EXPECT_EQ(numberSet.size(), 4);

    printf("Set MoveToListNodeFront test passed\n");
}

/**
 * @brief 综合测试：Set特有的场景和性能测试
 */
TEST(NFShmHashSetWithListAdvancedTest, SetSpecificScenarios)
{
    printf("========== Set Specific Scenarios Test ==========\n");

    // 测试1：唯一性保证测试
    printf("Test 1: Uniqueness guarantee\n");
    {
        NFShmHashSetWithList<int, 50> uniqueSet;
        uniqueSet.CreateInit();

        // 尝试插入重复元素
        std::vector<int> test_data = {5, 3, 8, 3, 1, 8, 9, 1, 5, 7};

        for (int val : test_data)
        {
            auto result = uniqueSet.insert_list_sorted(val);
            printf("  Inserting %d: %s\n", val, result.second ? "Success" : "Duplicate");
        }

        printf("Final unique set (sorted):\n");
        std::set<int> expected_unique(test_data.begin(), test_data.end());
        std::vector<int> actual_values;

        for (auto it = uniqueSet.list_begin(); it != uniqueSet.list_end(); ++it)
        {
            printf("  %d\n", *it);
            actual_values.push_back(*it);
        }

        // 验证唯一性和排序
        EXPECT_TRUE(std::is_sorted(actual_values.begin(), actual_values.end()));
        EXPECT_EQ(uniqueSet.size(), expected_unique.size());

        std::vector<int> expected_values(expected_unique.begin(), expected_unique.end());
        EXPECT_EQ(actual_values, expected_values);
    }

    // 测试2：复杂对象的排序
    printf("\nTest 2: Complex object sorting\n");
    {
        NFShmHashSetWithList<TaskInfo, 30> taskSet;
        taskSet.CreateInit();

        std::vector<TaskInfo> tasks = {
            TaskInfo(3, "Task C", "Development"), TaskInfo(1, "Task A", "Testing"), TaskInfo(2, "Task B", "Documentation"), TaskInfo(1, "Task A", "Development"), // 不同category的同名任务
            TaskInfo(3, "Task D", "Development"),
        };

        for (const auto& task : tasks)
        {
            auto result = taskSet.insert_list_sorted(task);
            printf("  Inserting Task (Priority:%d, %s, %s): %s\n", task.priority, task.name.c_str(), task.category.c_str(), result.second ? "Success" : "Duplicate");
        }

        printf("Final task set (sorted by priority, then category, then name):\n");
        for (auto it = taskSet.list_begin(); it != taskSet.list_end(); ++it)
        {
            printf("  Priority:%d '%s' (%s)\n", it->priority, it->name.c_str(), it->category.c_str());
        }

        // 验证排序正确性
        std::vector<TaskInfo> sorted_tasks;
        for (auto it = taskSet.list_begin(); it != taskSet.list_end(); ++it)
        {
            sorted_tasks.push_back(*it);
        }

        EXPECT_TRUE(std::is_sorted(sorted_tasks.begin(), sorted_tasks.end()));
        EXPECT_EQ(taskSet.size(), tasks.size()); // 所有任务都应该是唯一的
    }

    // 测试3：性能测试
    printf("\nTest 3: Performance test\n");
    {
        const int TEST_SIZE = 200;
        NFShmHashSetWithList<int, TEST_SIZE> perfSet;
        perfSet.CreateInit();

        // 生成随机但唯一的数据
        std::vector<int> unique_values;
        for (int i = 1; i <= TEST_SIZE; ++i)
        {
            unique_values.push_back(i);
        }

        std::random_device rd;
        std::mt19937 gen(rd());
        std::shuffle(unique_values.begin(), unique_values.end(), gen);

        // 测试insert_list_sorted性能
        auto start = std::chrono::high_resolution_clock::now();
        for (int value : unique_values)
        {
            perfSet.insert_list_sorted(value);
        }
        auto end = std::chrono::high_resolution_clock::now();
        auto insert_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        printf("insert_list_sorted %d unique elements took %lld microseconds\n", TEST_SIZE, insert_time.count());

        // 验证排序正确性和唯一性
        std::vector<int> sorted_values;
        for (auto it = perfSet.list_begin(); it != perfSet.list_end(); ++it)
        {
            sorted_values.push_back(*it);
        }

        EXPECT_TRUE(std::is_sorted(sorted_values.begin(), sorted_values.end()));
        EXPECT_EQ(perfSet.size(), TEST_SIZE);

        // 验证所有值都存在且唯一
        for (int i = 1; i <= TEST_SIZE; ++i)
        {
            EXPECT_EQ(perfSet.count(i), 1);
        }

        // 测试move_to_list_sorted性能
        start = std::chrono::high_resolution_clock::now();
        for (int i = 0; i < 50; ++i) // 移动50个元素
        {
            auto it = perfSet.find(i + 1);
            if (it != perfSet.end())
            {
                perfSet.move_to_list_sorted(it);
            }
        }
        end = std::chrono::high_resolution_clock::now();
        auto move_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        printf("move_to_list_sorted 50 elements took %lld microseconds\n", move_time.count());

        // 再次验证排序正确性
        sorted_values.clear();
        for (auto it = perfSet.list_begin(); it != perfSet.list_end(); ++it)
        {
            sorted_values.push_back(*it);
        }
        EXPECT_TRUE(std::is_sorted(sorted_values.begin(), sorted_values.end()));
    }

    printf("Set Specific Scenarios test passed\n");
}

